<template>
  <div class="date-container">
    <div class="date">
      <div @click="updateMonth(1)" class="prev-month">&lt;&lt;</div>
      {{ currrentDate }}
      <div @click="updateMonth(2)" class="next-month">&gt;&gt;</div>
    </div>
    <div class="week">
      <div v-for="item in weekArr" :key="item">
        {{ item }}
      </div>
    </div>
    <div class="date-list">
      <div
        @click="dateChange(index)"
        v-for="(item, index) in dateArr"
        :key="index"
        class="date-item"
      >
        <div
          :class="{
            'date-number': true,
            today:
              yearAndMonthIsCurrent && item === currentDate && highlightToday,
            'selected-date': selectedDate && item == selectedDate,
          }"
        >
          {{ item }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    // 调用者传入的日期
    modelValue: {
      default: `${new Date().getFullYear()}/${
        new Date().getMonth() + 1
      }/${new Date().getDate()}`,
      type: String,
      required: true,
    },
    // 是否需要显示当天的日期
    highlightToday: {
      default: true,
      type: Boolean,
    },
    // 当天日期数值高亮颜色
    todayColor: { 
      default:'#55748f',
      type: String,
    },
    // 用户选择日期高亮颜色
    selectedColor:{
      default:'#30404e',
      type: String,
    }
  },
  data() {
    return {
      // 当前年份
      currentYear: new Date().getFullYear(),
      // 当前月份
      currentMonth: new Date().getMonth() + 1,
      // 当前日期
      currentDate: new Date().getDate(),
      // 星期数组
      weekArr: ["日", "一", "二", "三", "四", "五", "六"],
      // 每月的日期数组
      dateArr: [],
      // 1-12月每个月的天数
      daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
      // 当前被点击的日期
      selectedDate: 0,
    };
  },
  computed: {
    // 当前日期
    currrentDate() {
      return `${this.currentYear}/${this.currentMonth}/${this.currentDate}`;
    },
    // 年份和月份是否都是当前的年份和月份
    yearAndMonthIsCurrent() {
      return (
        this.currentYear === new Date().getFullYear() &&
        this.currentMonth === new Date().getMonth() + 1
      );
    },
  },
  created() {
    // 初始化当前月份的日期数组
    this.dateArrInit();
    // 计算平年中2月份的天数
    this.computedFibruaryDays();
    this.selectedDate = this.modelValue.split("/").pop().padStart(2, 0);
  },
  watch: {
    // 监视月份变化
    currentMonth() {
      // 更新当前月份的日期数组
      this.dateArrInit();
    },
    // 监视年份的变化
    currentYear() {
      // 更新当前月份的日期数组
      this.dateArrInit();
    },
  },
  methods: {
    // index: 被点击的日期在日期数组dateArr中的索引
    dateChange(index) {
      // 更新当前日期数值
      if (!this.dateArr[index]) {
        return false;
      }
      this.selectedDate = this.dateArr[index];
      // 触发自定义事件, 分发用户选择的日期
      this.$emit(
        "update:modelValue",
        `${this.currentYear}/${this.currentMonth}/${this.selectedDate}`
      );
      // 关闭日期选择框
      this.$emit("hidden", false);
    },
    // 更新月份
    updateMonth(flag) {
      // 月份-1
      if (flag === 1) {
        if (this.currentMonth > 1) {
          this.currentMonth -= 1;
        } else {
          this.currentYear -= 1;
          this.currentMonth = 12;
        }
      } else if (flag === 2) {
        // 月份+1
        if (this.currentMonth < 12) {
          this.currentMonth += 1;
        } else {
          this.currentYear += 1;
          this.currentMonth = 1;
        }
      }
    },
    // 计算平年中二月份的天数
    computedFibruaryDays() {
      const year = new Date().getFullYear();
      if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) {
        this.daysInMonth[1] = 28;
      }
    },
    // 初始化dateArr
    dateArrInit() {
      this.dateArr.length = 40;
      // 使用空字符填充数组
      this.dateArr.fill("", 0, 40);
      // 获取当月的天数
      const days = this.daysInMonth[this.currentMonth - 1];
      // 获取当月1号是星期几
      const mondayWeek = new Date(
        `${this.currentYear}/${this.currentMonth}/1`
      ).getDay();
      // 向月份日期数组中填充合适的日期数值, 日期和星期必须对应, 所以需要进行一定的偏移,
      for (let i = 1; i <= days; i++) {
        this.dateArr[mondayWeek + i - 1] = i;
      }
    },
  },
};
</script>

<style>
.date-container {
  width: 100%;
  height: 100%;
  min-height: 320px;
  box-sizing: border-box;
  border: 1px solid #eee;
  background: #fff;
  border-radius: 4px;
}
.date {
  display: flex;
  justify-content: space-around;
  padding: 10px;
  font-weight: 700;
  text-align: center;
}

.prev-month,
.next-month {
  cursor: pointer;
}
.week {
  display: flex;
  height: 50px;
  line-height: 50px;
  justify-content: center;
}
.week > div {
  flex: 1;
  text-align: center;
}
.date-list {
  display: flex;
  flex-wrap: wrap;
  min-height: 240px;
  height: calc(100% - 100px);
}

.date-item {
  position: relative;
  box-sizing: border-box;
  width: calc(100% / 7);
  text-align: center;
  cursor: pointer;
  /* border: 1px solid #eee; */
}
.date-number {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 40px;
  min-height: 40px;
  line-height: 40px;
}
.today {
  /* 直接使用js变量 */
  background: v-bind(todayColor) !important;
  border-radius: 50%;
  color: #fff;
}
.selected-date {
  background: v-bind(selectedColor);
  border-radius: 50%;
  color: #fff;
}
</style>